Java Animation Memory Overload [on hold]

Posted by user2425429 on Game Development See other posts from Game Development or by user2425429
Published on 2013-06-26T15:27:03Z Indexed on 2013/06/26 16:30 UTC
Read the original article Hit count: 263

Filed under:
|
|

I need a way to reduce the memory usage of these programs while keeping the functionality. Every time I add 50 milliseconds or so to the set&display loop in AnimationTest1, it throws an out of memory error. Here is the code I have now:

import java.awt.DisplayMode;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Polygon;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import javax.swing.ImageIcon;

public class AnimationTest1 {

public static void main(String args[]) {
    AnimationTest1 test = new AnimationTest1();
    test.run();
}

private static final DisplayMode POSSIBLE_MODES[] = {
    new DisplayMode(800, 600, 32, 0),
    new DisplayMode(800, 600, 24, 0),
    new DisplayMode(800, 600, 16, 0),
    new DisplayMode(640, 480, 32, 0),
    new DisplayMode(640, 480, 24, 0),
    new DisplayMode(640, 480, 16, 0)
};

private static final long DEMO_TIME = 4000;

private ScreenManager screen;
private Image bgImage;
private Animation anim;


public void loadImages() {
    // create animation
    List<Polygon> polygons=new ArrayList();
    int[] x=new int[]{20,4,4,20,40,56,56,40};
    int[] y=new int[]{20,32,40,44,44,40,32,20};
    polygons.add(new Polygon(x,y,8));
    anim = new Animation();
    //# of frames 
    long startTime = System.currentTimeMillis();
    long currTimer = startTime;
    long elapsedTime = 0;
    boolean animated = false;
    Graphics2D g = screen.getGraphics();
    int width=200;
    int height=200;
    //set&display loop
    while (currTimer - startTime < DEMO_TIME*2) {
        //draw the polygons
        if(!animated){
            for(int j=0; j<polygons.size();j++){
                for(int pos=0; pos<polygons.get(j).npoints; pos++){
                    polygons.get(j).xpoints[pos]+=1;
                    }
            }
            anim.setNewPolyFrame(polygons , width , height , 64);
        }
        else{
        // update animation
        anim.update(elapsedTime);
        draw(g);
        g.dispose();
        screen.update();
        try{
            Thread.sleep(20);
        }
        catch(InterruptedException ie){}
        }
        if(currTimer - startTime == DEMO_TIME)
            animated=true;
        elapsedTime = System.currentTimeMillis() - currTimer;
        currTimer += elapsedTime;
    }
}


public void run() {
    screen = new ScreenManager();
    try {
        DisplayMode displayMode =
            screen.findFirstCompatibleMode(POSSIBLE_MODES);
        screen.setFullScreen(displayMode);
        loadImages();
    }
    finally {
         screen.restoreScreen();
    }
}


public void draw(Graphics g) {
    // draw background
    g.drawImage(bgImage, 0, 0, null);

    // draw image
    g.drawImage(anim.getImage(), 0, 0, null);
}

}

ScreenManager:

import java.awt.Color;
import java.awt.DisplayMode;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.KeyListener;
import java.awt.event.MouseListener;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class ScreenManager extends JPanel {

private GraphicsDevice device;

/**
    Creates a new ScreenManager object.
*/
public ScreenManager() {
  GraphicsEnvironment environment=GraphicsEnvironment.getLocalGraphicsEnvironment();
    device = environment.getDefaultScreenDevice();
    setBackground(Color.white);
}

/**
    Returns a list of compatible display modes for the
    default device on the system.
*/
public DisplayMode[] getCompatibleDisplayModes() {
    return device.getDisplayModes();
}


/**
    Returns the first compatible mode in a list of modes.
    Returns null if no modes are compatible.
*/
public DisplayMode findFirstCompatibleMode(
    DisplayMode modes[])
{
    DisplayMode goodModes[] = device.getDisplayModes();
    for (int i = 0; i < modes.length; i++) {
        for (int j = 0; j < goodModes.length; j++) {
            if (displayModesMatch(modes[i], goodModes[j])) {
                return modes[i];
            }
        }

    }

    return null;
}


/**
    Returns the current display mode.
*/
public DisplayMode getCurrentDisplayMode() {
    return device.getDisplayMode();
}


/**
    Determines if two display modes "match". Two display
    modes match if they have the same resolution, bit depth,
    and refresh rate. The bit depth is ignored if one of the
    modes has a bit depth of DisplayMode.BIT_DEPTH_MULTI.
    Likewise, the refresh rate is ignored if one of the
    modes has a refresh rate of
    DisplayMode.REFRESH_RATE_UNKNOWN.
*/
public boolean displayModesMatch(DisplayMode mode1,
    DisplayMode mode2)
{
    if (mode1.getWidth() != mode2.getWidth() ||
        mode1.getHeight() != mode2.getHeight())
    {
        return false;
    }

    if (mode1.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI &&
        mode2.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI &&
        mode1.getBitDepth() != mode2.getBitDepth())
    {
        return false;
    }

    if (mode1.getRefreshRate() !=
        DisplayMode.REFRESH_RATE_UNKNOWN &&
        mode2.getRefreshRate() !=
        DisplayMode.REFRESH_RATE_UNKNOWN &&
        mode1.getRefreshRate() != mode2.getRefreshRate())
     {
         return false;
     }

     return true;
}


/**
    Enters full screen mode and changes the display mode.
    If the specified display mode is null or not compatible
    with this device, or if the display mode cannot be
    changed on this system, the current display mode is used.
    <p>
    The display uses a BufferStrategy with 2 buffers.
*/
public void setFullScreen(DisplayMode displayMode) {
    JFrame frame = new JFrame();
    frame.setUndecorated(true);
    frame.setIgnoreRepaint(true);
    frame.setResizable(true);

    device.setFullScreenWindow(frame);
    if (displayMode != null &&
        device.isDisplayChangeSupported())
    {
        try {
            device.setDisplayMode(displayMode);
        }
        catch (IllegalArgumentException ex) { }
    }
    frame.createBufferStrategy(2);
    Graphics g=frame.getGraphics();
    g.setColor(Color.white);
    g.drawRect(0, 0, frame.WIDTH, frame.HEIGHT);
    frame.paintAll(g);
    g.setColor(Color.black);
    g.dispose();
}


/**
    Gets the graphics context for the display. The
    ScreenManager uses double buffering, so applications must
    call update() to show any graphics drawn.
    <p>
    The application must dispose of the graphics object.
*/
public Graphics2D getGraphics() {
    Window window = device.getFullScreenWindow();
    if (window != null) {
        BufferStrategy strategy = window.getBufferStrategy();
        return (Graphics2D)strategy.getDrawGraphics();
    }
    else {
        return null;
    }
}


/**
    Updates the display.
*/
public void update() {
    Window window = device.getFullScreenWindow();
    if (window != null) {
        BufferStrategy strategy = window.getBufferStrategy();
        if (!strategy.contentsLost()) {
            strategy.show();
        }
    }
    // Sync the display on some systems.
    // (on Linux, this fixes event queue problems)
    Toolkit.getDefaultToolkit().sync();
}


/**
    Returns the window currently used in full screen mode.
    Returns null if the device is not in full screen mode.
*/
public Window getFullScreenWindow() {
    return device.getFullScreenWindow();
}


/**
    Returns the width of the window currently used in full
    screen mode. Returns 0 if the device is not in full
    screen mode.
*/
public int getWidth() {
    Window window = device.getFullScreenWindow();
    if (window != null) {
        return window.getWidth();
    }
    else {
        return 0;
    }
}


/**
    Returns the height of the window currently used in full
    screen mode. Returns 0 if the device is not in full
    screen mode.
*/
public int getHeight() {
    Window window = device.getFullScreenWindow();
    if (window != null) {
        return window.getHeight();
    }
    else {
        return 0;
    }
}


/**
    Restores the screen's display mode.
*/
public void restoreScreen() {
    Window window = device.getFullScreenWindow();
    if (window != null) {
        window.dispose();
    }
    device.setFullScreenWindow(null);
}


/**
    Creates an image compatible with the current display.
*/
public BufferedImage createCompatibleImage(int w, int h,
    int transparency)
{
    Window window = device.getFullScreenWindow();
    if (window != null) {
        GraphicsConfiguration gc =
            window.getGraphicsConfiguration();
        return gc.createCompatibleImage(w, h, transparency);
    }
    return null;
}
}

Animation:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Polygon;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

/**
    The Animation class manages a series of images (frames) and
    the amount of time to display each frame.
*/
public class Animation {
private ArrayList frames;
private int currFrameIndex;
private long animTime;
private long totalDuration;


/**
    Creates a new, empty Animation.
*/
public Animation() {
    frames = new ArrayList();
    totalDuration = 0;
    start();
}


/**
    Adds an image to the animation with the specified
    duration (time to display the image).
*/
public synchronized void addFrame(BufferedImage image, long duration){
    ScreenManager s = new ScreenManager();
    totalDuration += duration;
    frames.add(new AnimFrame(image, totalDuration));
}


/**
    Starts the animation over from the beginning.
*/
public synchronized void start() {
    animTime = 0;
    currFrameIndex = 0;
}


/**
    Updates the animation's current image (frame), if
    necessary.
*/
public synchronized void update(long elapsedTime) {
    if (frames.size() >= 1) {
        animTime += elapsedTime;

        /*if (animTime >= totalDuration) {
            animTime = animTime % totalDuration;
            currFrameIndex = 0;
        }*/

        while (animTime > getFrame(0).endTime) {
            frames.remove(0);
        }
    }
}

/**
    Gets the Animation's current image. Returns null if this
    animation has no images.
*/
public synchronized Image getImage() {
    if (frames.size() > 0&&!(currFrameIndex>=frames.size())) {
        return getFrame(currFrameIndex).image;
    }
    else{
        System.out.println("There are no frames!");
        System.exit(0);
    }
    return null;
}


private AnimFrame getFrame(int i) {
    return (AnimFrame)frames.get(i);
}


private class AnimFrame {

    Image image;
    long endTime;

    public AnimFrame(Image image, long endTime) {
        this.image = image;
        this.endTime = endTime;
    }
}
public void setNewPolyFrame(List<Polygon> polys,int imagewidth,int imageheight,int 
time){
    BufferedImage image=new BufferedImage(imagewidth, imageheight, 1);
    Graphics g=image.getGraphics();
    for(int i=0;i<polys.size();i++){
        g.drawPolygon(polys.get(i));
    }
    addFrame(image,time);
    g.dispose();
}
}

© Game Development or respective owner

Related posts about java

Related posts about animation